package com.study.easyexcel.business.template;

import com.alibaba.excel.constant.OrderConstant;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import org.apache.poi.ss.usermodel.*;

import java.util.HashMap;
import java.util.function.BiConsumer;

/**
 * 统一样式处理器，数据填充的基础样式填充
 *
 * @author yuhuan
 * @date 2024/1/2
 */
public class UniversalGroupStyle implements CellWriteHandler {

    public static final String STYLE_FILL_KEY = "Style";

    /**
     * 样式行，以及对应的列索引，索引从0开始，多个列逗号拼接，-1表示全列。例如：[2:1,2]表示第3三行的2、3列
     */
    protected HashMap<Integer, String> styleRowColMap;

    /**
     * 公式行，配合{@link #setCellFormula(CellWriteHandlerContext, Cell)}可定制单元格公式
     */
    protected HashMap<Integer, String> formulaRowColMap;

    /**
     * 将写入器尽量往后排序，排序值高于{@link OrderConstant#FILL_STYLE}即可；否则该处理器定义的样式可能会被EasyExcel自己的样式填
     * 充器覆盖
     */
    @Override
    public int order() {
        return 50001;
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        Cell cell = context.getCell();
        int rowIndex = cell.getRowIndex();
        // 样式行
        if (checkRowColMap(this.styleRowColMap, rowIndex)) {
            setCellStyle(context, cell, styleRowColMap, this::setUnifiedCellStyle);
        }
        // 公式行
        if (checkRowColMap(this.formulaRowColMap, rowIndex)) {
            setCellStyle(context, cell, formulaRowColMap, this::setCellFormula);
        }
    }

    public void setStyleRowColMap(HashMap<Integer, String> styleRowColMap) {
        this.styleRowColMap = styleRowColMap;
    }

    public void setFormulaRowColMap(HashMap<Integer, String> formulaRowColMap) {
        this.formulaRowColMap = formulaRowColMap;
    }

    /**
     * 重写后，可定制公式的填充
     */
    protected void setCellFormula(CellWriteHandlerContext context, Cell cell) {

    }

    /**
     * 重写后，可定制样式的填充
     */
    protected void setUnifiedCellStyle(CellWriteHandlerContext context, Cell cell) {
        Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
        CellStyle cellStyle = createCellUnifiedStyle(workbook, cell.getColumnIndex());
        cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cell.setCellStyle(cellStyle);
    }

    /**
     * 添加统一的单元格样式
     *
     * @param columnIndex 当前列
     */
    protected CellStyle createCellUnifiedStyle(Workbook workbook, int columnIndex) {
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontName("宋体");
        // 字体大小
        font.setFontHeightInPoints((short) 10);
        cellStyle.setFont(font);
        if (columnIndex == 0) {
            // 首个单元格上下左右都有边框
            cellStyle.setBorderTop(BorderStyle.THIN);
            cellStyle.setBorderLeft(BorderStyle.MEDIUM);
            cellStyle.setBorderRight(BorderStyle.THIN);
            cellStyle.setBorderBottom(BorderStyle.THIN);
        } else if (columnIndex == 8) {
            // 补齐尾部单元格的粗体边框
            cellStyle.setBorderRight(BorderStyle.MEDIUM);
        } else if (columnIndex == 4) {
            // 补齐中间单元格的细边框
            cellStyle.setBorderRight(BorderStyle.THIN);
        }
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        return cellStyle;
    }

    /**
     * 检查当前前行是否存在自定义的样式
     *
     * @param rowColMap 行列索引映射
     * @param rowIndex  当前的行索引
     */
    protected boolean checkRowColMap(HashMap<Integer, String> rowColMap, int rowIndex) {
        return rowColMap != null && rowColMap.size() > 0 && rowColMap.get(rowIndex) != null;
    }

    /**
     * 行列样式检查，检查当前单元格是否在样式的行列索引中被定义
     *
     * @param rowColMap 样式行或者公式行
     * @param performer 填充样式的执行逻辑体
     */
    protected void setCellStyle(CellWriteHandlerContext context, Cell cell, HashMap<Integer, String> rowColMap, BiConsumer<CellWriteHandlerContext, Cell> performer) {
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();
        if (rowColMap.get(rowIndex).contains("-1")) {
            // 全列设置样式
            performer.accept(context, cell);
        } else {
            // 指定列设置样式
            String[] titleStyleColIndexList = rowColMap.get(rowIndex).split(",");
            for (String index : titleStyleColIndexList) {
                if (columnIndex == Integer.parseInt(index)) {
                    performer.accept(context, cell);
                }
            }
        }
    }
}
